package com.uw.uwrpc.core.cluster.router;

import com.uw.uwrpc.core.api.Router;
import com.uw.uwrpc.core.constant.UWConstant;
import com.uw.uwrpc.core.meta.InstanceMeta;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

@Slf4j
public class GrayRouter implements Router<InstanceMeta> {

    private final int grayRatio;

    public GrayRouter(int grayRatio) {
        this.grayRatio = grayRatio;
    }

    @Override
    public List<InstanceMeta> route(List<InstanceMeta> instanceList) {
        if (CollectionUtils.isEmpty(instanceList) || instanceList.size() <= 1) {
            return instanceList;
        }


        List<InstanceMeta> notGrayInstanceList = new ArrayList<>();
        List<InstanceMeta> grayInstanceList = new ArrayList<>();

        for (InstanceMeta instanceMeta : instanceList) {
            Map<String, String> parameters = instanceMeta.getParameters();
            if (CollectionUtils.isEmpty(parameters)) {
                notGrayInstanceList.add(instanceMeta);
                continue;
            }

            String grayString = parameters.getOrDefault(UWConstant.gray, "false");
            if ("true".equalsIgnoreCase(grayString)) {
                grayInstanceList.add(instanceMeta);
                continue;
            }

            notGrayInstanceList.add(instanceMeta);
        }

        log.debug("grayRouter grayNodes/normalNodes,grayRatio ===> {}/{},{}",
                grayInstanceList.size(), notGrayInstanceList.size(), grayRatio);

        // 如果灰度比率小于等于0，则直接返回非灰度节点
        if (grayRatio <= 0) {
            return notGrayInstanceList;
        }
        // 如果灰度比率大于等于100，则直接返回灰度节点
        if (grayRatio >= 100) {
            return grayInstanceList;
        }

        if (ThreadLocalRandom.current().nextInt(100) < grayRatio) {
            // 随机数小于灰度比率，则返回灰度节点
            log.debug(" grayRouter grayInstanceList ===> {}", grayInstanceList);
            return grayInstanceList;
        } else {
            // 随机数大于等于灰度比率，则返回非灰度节点
            log.debug(" grayRouter notGrayInstanceList ===> {}", notGrayInstanceList);
            return notGrayInstanceList;
        }

    }
}
